#include "stdio.h"
#include "FreeRTOS.h"
#include "task.h"

#include "usart.h"
#include "time.h"
#include "iic.h"

#include "bmp.h"
#include "oled.h"
#include "oled_windows.h"

#include "key.h"
#include "matrix_key.h"

#include "fan.h"
#include "wifi.h"
#include "at24cxx.h"

#include "drv_as608.h"
#include "ser_as608.h"
//#include "rc522_config.h"
//#include "rc522_function.h"
//#include "led.h"
//#include "beep.h"
//#include "adc.h"
//#include "dht11.h"


#define PASSWORD_ADDR 0X40	//密码存储初始地址--AT24Cxx，共24个字节，前12字节为管理员用户，后12字节为普通用户

//-----------------------------通讯协议----------------------------------
//传感器数据
typedef struct SensorData
{
    char  sensor_name[15];
    char  sensor_value;
}SensorData;

//设备状态
typedef struct DeviceData
{
    char  device_name[15];
    char  device_status;	//1 on,0 off
    char  device_level;
}DeviceData;

//上传数据
typedef struct UpData
{
    int room_num;
    SensorData sensor_data[6];
    DeviceData device_data[6];
}UpData;

//下发数据
typedef struct DownData
{
    int room_num;
    DeviceData device_data;
}DownData;

//数据包
 typedef struct Message
 {
     char message_type;		//0--传感器数据和设备状态、1--控制指令
     char message_content[400];	//	memcpy(message_content,up_data | down_data,sizeof(up_data | down_data))
     int sum_check;	//strlen(message_content)//和校验
 }Message;
//------------------------------------------------------------------------------------
//转发消息数据和标志
Message message;
char message_flag=0;

//设备和传感器数据
char led_status;
char fan_status;
char fan_level;
char temperature;
char humidity;
char light;

//OLED屏幕当前所在行数
char oled_line = 1;
//按键1-3是被点击
char key1_status;
char key2_status;
char key3_status;

//矩阵键盘数据和标志
char mtri_key_value = 0;//矩阵键盘键值
char password_input[12] = {0};
char password[2][12] = {{"123"}};//用户密码,password[0]为管理员用户，password[1]为普通用户
char password_input_index = 0;//输入密码的当前位数
char password_pattern = 0;//0表示校验模式，1验证原密码，2输入新密码
char password_flag = 0;//0密码错误，1密码通过
char pwd_change_flag = 0;//密码是否有修改0：否，1：是
char input_pwd_change_flag = 0;//输入的密码是否有修改

//FreeRTOS任务句柄
TaskHandle_t matrix_key_handle;	//矩形键盘任务句柄
TaskHandle_t oled_handle;	//OLED屏任务句柄
TaskHandle_t forWard_data_handle;	//数据转发任务句柄



//显示屏任务			key1--下翻  		key2--确认		key3--返回上一级
void displayOledTask(void *pvParameters)
{
	int k;
	window_menu_line1();
	while(1)	//--主界面
	{
		if(key1_status == 1)
		{
			key1_status = 0;
			switch (oled_line)	//主界面行选中情况
			{
				case 1:
					window_menu_line2();
					break;
				case 2:
					window_menu_line3();
					break;
				case 3:
					window_menu_line1();
					break;
			}	
		}
		if(key2_status == 1)	//--登陆界面
		{
			key2_status = 0;
			window_login();
			while(1)	
			{
				
				if(password_flag == 1)	//--设备状态界面
				{
					password_flag = 0;
					window_device_status();
					while(1)	//----设备状态界面动态数据展示
					{
						//---LED灯
						if(led_status == 1)		
						{
							OLED_ShowChinese(38,16,0,12,1);	//开
						}
						else
						{
							OLED_ShowChinese(38,16,1,12,1);	//关
						}
						//--fan风扇
						if(fan_status == 1)	
						{
							OLED_ShowChinese(96,16,0,12,1);	//开
						}
						else
						{
							OLED_ShowChinese(96,16,1,12,1);	//关
						}
						//--温度
						OLED_ShowNum(38,30,temperature,2,12,1);
						//--湿度
						OLED_ShowNum(96,30,humidity,2,12,1);
						//--光照强度
						OLED_ShowNum(62,44,light,2,12,1)
						OLED_Refresh();
						
						if(key3_status == 1)	//设备状态界面返回登陆界面
						{
							key3_status = 0;
							window_login();
							break;
						}
					}
				}
				
				if(key3_status == 1)	//登陆界面返回主界面
				{
					key3_status = 0;
					window_menu_line1();
					break;
				}
				if(input_pwd_change_flag == 1)	//登陆界面动态显示当前已输入的密码位数
				{	
					input_pwd_change_flag = 0;
					for(k=0;k<8;k++)
					{
						OLED_ShowChar(30+8*k,30,0,12,1);//清空
					}
					
					for(k=0;k<password_input_index;k++)
					{
						OLED_ShowChar(30+8*k,30,42,12,1);//*
					}
					OLED_Refresh();	
				}				
			}
		}
	}
}

//矩形键盘任务			'#'--确认输入			"***#"--修改密码
void matrixKeyTask(void *pvParameters)
{
	char i,j,
	u16 addr = PASSWORD_ADDR;
	taskENTER_CRITICAL();
	for(i=0;i < 2;i++)
	{
		for(j=0;j < 12;j++)
		{
			password[i][j] = at24cxxRdata(addr++);
		}
	}
	taskEXIT_CRITICAL();
	addr = PASSWORD_ADDR;
	while(1)
	{	
//		printf("%d\n",password_flag);
		matrixKeyScan();	//矩阵键盘扫描
		//如果密码做了修改，及时保存到AT24Cxx芯片中
		if(pwd_change_flag == 1)
		{
			taskENTER_CRITICAL();
			for(i=0;i<2;i++)
			{
				for(j=0;j<12;j++)
				{	
					at24cxxWdata(addr++,password[i][j]);
				}
			}
			taskEXIT_CRITICAL();
			addr = PASSWORD_ADDR;
			pwd_change_flag = 0;
			printf("new password is ok!\n");
		}
		
		if(mtri_key_value == 'D')	//退位健
		{
			password_input[--password_input_index] = 0;
			mtri_key_value = 0;
			input_pwd_change_flag = 1;
		}
		
		//如果其他值则保存输入值置于输入密码数组中
		else if(mtri_key_value != '#' && mtri_key_value != 0 && password_input_index<8)
		{
			password_input[password_input_index++] = mtri_key_value;
			mtri_key_value = 0;
			input_pwd_change_flag = 1;
		}
		
	}
}

//数据转发任务
void forWardDataTask(void *pvParameters)
{
	char i;
	char AT_commend[128];
	while(1)
	{
		if(message_flag == 1)
		{
			message_flag = 0;
			if(message.message_type  == 0)	//上传数据
			{
				printf("22222222222222222222222222222222222222\n");
				sprintf(AT_commend,"AT+CIPSEND=%d,%d\r\n",0,sizeof(message));
				taskENTER_CRITICAL();
				usartSendStr(USART2,AT_commend,sizeof(AT_commend));
				taskEXIT_CRITICAL();
				
				vTaskDelay(200);
				taskENTER_CRITICAL();
				usartSendStr(USART2,(char*)&message,sizeof(message));
				taskEXIT_CRITICAL();	
			}
			
			else if(message.message_type  == 1)	//下发数据
			{
				printf("33333333333333333333333333333333333333333333\n");
				sprintf(AT_commend,"AT+CIPSEND=%d,%d\r\n",i,sizeof(message));
				for(i=0;i<5;i++)
				{
					taskENTER_CRITICAL();
					usartSendStr(USART2,AT_commend,sizeof(AT_commend));
					taskEXIT_CRITICAL();
					
					vTaskDelay(200);
					taskENTER_CRITICAL();
					usartSendStr(USART2,(char*)&message,sizeof(message));
					taskEXIT_CRITICAL();
				}
			}
		}
	}		
}

//主程序入口
int main(){
	//中断优先级分组
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);	
	usart1Init();//usart1初始化，用于输出调试信息

	tim3Init();//基本定时器7初始化--延时定时器
	tim6Init();//基本定时器6初始化--按键复用判断定时器
	tim2Init();//通用定时器2初始化--定时进入中断获取传感器数据获取

	//按键1，2，3，4初始化
	keyInit(GPIO_Pin_4);
	keyInit(GPIO_Pin_5);
	keyInit(GPIO_Pin_6);
	key4Init();
	extiInit();//按键外部中断初始化
	
	OLED_Init();	//OLED屏幕初始化
	iicInit();
	matrixKeyInit();	//矩形按键初始化

	usart2Init();	//usart2初始化，用于与ESP12S连接实现无线通信
	usart3Init(usart3_baund)
//	wifiInit();//wifi初始化	

	TIM_Cmd(TIM2, ENABLE);//定时器中断开启
	xTaskCreate(displayOledTask,"displayOledTask",256,NULL,2,oled_handle);
	xTaskCreate(matrixKeyTask,"matrixKeyTask",256,NULL,2,matrix_key_handle);
	xTaskCreate(forWardDataTask,"forWardDataTask",256,NULL,2,forWard_data_handle);
	vTaskStartScheduler();
	
}









//u8 ucStatusReturn;    //返回RFID状态
//u8 ucArray_ID [ 4 ];	 //先后存放IC卡的类型和UID(IC卡序列号)		

////RFID射频识别
//void rc522Task(void *pvParameters)
//{
//	while(1)
//	{
//		//RC522读取IC卡，进入范围则蜂鸣器提示
//		taskENTER_CRITICAL();
//		ucStatusReturn = PcdRequest(PICC_REQALL, ucArray_ID);
//		taskEXIT_CRITICAL();
//		if(ucStatusReturn == MI_OK  )
//		{
//			beepOpen();
//			vTaskDelay(300);
//			beepClose();
//		}
//		vTaskDelay(300);
//	}
//}

//	tim1Init();//高级定时器1初始化--用于led3灯的pwm设置
//	tim12Init();//通用定时器12初始化--用于fan风扇的pwm设置
//	RC522_Init ();	//RFID-RC522射频识别初始化
//	PcdReset ();	//RFID-RC522复位
//	M500PcdConfigISOType ( 'A' );//设置RFID-RC522工作方
//	xTaskCreate(rc522Task,"rc522Task",128,NULL,2,rc522_handle);

//	//设备初始化
//	ledInit(GPIO_Pin_8);
//	ledInit(GPIO_Pin_9);
//	ledInit(GPIO_Pin_10);
//	beepInit();//蜂鸣器初始化
//	fanInit();//风扇由N型MOS管控制，需要在N端提供高电平导通
//	//传感器初始化
//	adcInit();		//adc初始化，用于获取光照传感器数据
//	dht11Init();	//dht11温湿度传感器初始化



